package com.cjl.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cjl.anno.OperLog;
import com.cjl.auth.service.SysDeptService;
import com.cjl.auth.service.SysOperLogService;
import com.cjl.commons.jwt.JwtHelper;
import com.cjl.commons.result.Result;
import com.cjl.commons.result.ResultCodeEnum;
import com.cjl.commons.utils.IPKit;
import com.cjl.model.system.SysDept;
import com.cjl.model.system.SysLoginLog;
import com.cjl.model.system.SysOperLog;
import com.cjl.vo.system.LoginVo;
import net.sf.jsqlparser.expression.operators.relational.JsonOperator;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Date;

@Component
@Aspect
public class OperLogAspect {
    @Autowired
    private SysOperLogService sysOperLogService;

    @Autowired
    private SysDeptService sysDeptService;

    @Pointcut("@annotation(com.cjl.anno.OperLog)")
    public void loginLogPointCut(){}

    @AfterReturning(returning = "res", value = "loginLogPointCut() && @annotation(operLog)")
    public void logAfter(JoinPoint joinPoint, Result res, OperLog operLog){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        SysOperLog sysOperLog = new SysOperLog();
        String token = request.getHeader("token");

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        Method method = methodSignature.getMethod();
        Parameter[] parameters = method.getParameters();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < parameters.length; i++) {
            stringBuilder.append(parameters[i].getName() + ":" + args[i] + ",");
        }
        String operParam = stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();

        String ipAddr = IPKit.getIpAddrByRequest(request);
        SysDept sysDept = sysDeptService.getById(JwtHelper.getUserId(token));

        sysOperLog.setTitle(operLog.title());
        sysOperLog.setBusinessType(operLog.businessType());
        sysOperLog.setMethod(method.getName());
        if(HttpMethod.GET.name().equals(request.getMethod())){
            sysOperLog.setRequestMethod("GET");
        } else if(HttpMethod.POST.name().equals(request.getMethod())){
            sysOperLog.setRequestMethod("POST");
        } else if(HttpMethod.PUT.name().equals(request.getMethod())){
            sysOperLog.setRequestMethod("PUT");
        } else if(HttpMethod.DELETE.name().equals(request.getMethod())){
            sysOperLog.setRequestMethod("DELETE");
        } else{
            sysOperLog.setRequestMethod("GET");
        }
        sysOperLog.setOperatorType("MANAGE");
        sysOperLog.setOperName(JwtHelper.getUsername(token));
        sysOperLog.setDeptName(sysDept.getName());
        sysOperLog.setOperUrl(request.getRequestURI());
        sysOperLog.setOperIp(ipAddr);
        sysOperLog.setOperParam(operParam);
        sysOperLog.setJsonResult(res.toString());
        sysOperLog.setStatus(res.getCode() == ResultCodeEnum.SUCCESS.getCode() ? 1 : 0);
        if(res.getCode() != ResultCodeEnum.SUCCESS.getCode()) {
            sysOperLog.setErrorMsg(res.getMessage());
        }
        sysOperLogService.save(sysOperLog);
        System.out.println("操作日志保存成功");
    }

}
